﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Gakita.Model.Enemies
{
    /* This class handles the logic for the rabbit enemy. Rabbits walk in a horizontal direction until they hit a wall or there is no land to       walk on, and then they turn around. Rabbits can be killed by the player, in which case they fall off the screen */
    class Rabbit
    {
        private Vector2 _startPosition;
        private Vector2 _bottomCenterPosition;
        private Vector2 _speed                      =       Vector2.Zero;
        private Vector2 _standardSpeed              =       new Vector2(-2, 0);
        private bool _isAlive                       =       true;

        public Vector2 _size                        =       new Vector2(0.7f, 0.9f);

        public Rabbit(Vector2 aBottomCenterPosition)
        {
            _startPosition = aBottomCenterPosition;
            _bottomCenterPosition = aBottomCenterPosition;
            _speed = _standardSpeed;
        }

        public void Update(float aElapsedTime, Level alevel)
        {
            // When the rabbit is alive, it checks whether it can keep walking in its' current direction. It will turn around if it can't.
            if (_isAlive == true)
            {
                float NewBottomCenterXPosition = _bottomCenterPosition.X + _speed.X * aElapsedTime;

                if (CantWalkInThatDirectionAnymore(alevel, NewBottomCenterXPosition))
                {
                    TurnAround();
                }
                
                _bottomCenterPosition += _speed * aElapsedTime;
            }
            // If the rabbit is not alive, but still inside the level, a gravity is added to allow the rabbit to fall off the screen.
            else if(RabbitIsInLevel())
            {
                Vector2 gravity = new Vector2(0, 9.82f);
               
                _bottomCenterPosition = _bottomCenterPosition + _speed * aElapsedTime + gravity * aElapsedTime * aElapsedTime;

                _speed = _speed + aElapsedTime * gravity;
            }
        }

        /* This method checks whether the rabbit is still within the level */
        private bool RabbitIsInLevel()
        {
            if (_bottomCenterPosition.Y > 21)
            {
                return false;
            }
            return true;
        }

        /* This method check whether the rabbit can keep walking in its' current direction, or if it needs to turn around */
        private bool CantWalkInThatDirectionAnymore(Level alevel, float aNewBottomCenterXPosition)
        {
            // If the position right bellow the rabbit is empty, there is no land to walk on, and it will have to turn around.
            if (alevel._tiles[(int) aNewBottomCenterXPosition, (int) _bottomCenterPosition.Y] == Level.Tile.T_EMPTY)
            {
                return true;
            }

            // If the position right infront of the rabbit is not empty, it will collide with a wall, and it will have to turn around.
            else if ((int)alevel._tiles[(int)(aNewBottomCenterXPosition+0.5f), (int) _bottomCenterPosition.Y - 1] > 0)
            {
                  return true;
            }

            return false;
        }

        /* This method is called when the player kills a rabbit. */
        public void Die()
        {
            _isAlive = false;
            _speed = new Vector2(-_speed.X, -5);
        }

        /* This method restores the rabbit to its' original state. It is called when the player dies to respawn rabbits */
        public void Reset()
        {
            _isAlive = true;
            _bottomCenterPosition = _startPosition;
            _speed = _standardSpeed;
        }

        /* This method allows the rabbit to turn around, by reversing it's speed */
        private void TurnAround()
        {
            _speed.X = -_speed.X;
        }

        public Vector2 GetPosition()
        {
            return _bottomCenterPosition;
        }

        public Vector2 GetSpeed()
        {
            return _speed;
        }

        public bool IsAlive()
        {
            return _isAlive;
        }
    }
}
